(function($) {    
    var DrawState = ujs.define('DrawState', 'ujs.subjects.draw', {
        SELECT : 0, //选择状态.        
        DRAWING : 1,    //绘制模式，包括绘制矩形，绘制线条等.
        RECT : 1.1,  //绘制矩形模式.
        LINE : 1.2  //绘制线条.
    });    
    /**
     * DrawPallet 构造函数.
     */
    var _DrawPallet = function(pallet, palletConfig) {        
        var _this = this;        
        //画板配置.
        this.palletConfig = palletConfig;
        
        this.pallet = $(pallet);
        
        this.palletContainer = $(palletConfig['palletContainer']);
        
        //初始状态为‘选择’板式.
        this.pallet.drawState = DrawState.SELECT;        
        //画笔配置.
        this.drawConfig = {
            onChange : function(){
                window.annotationPallet.isModified = true;
            }            
        };
        
        //终止绘制操作.
        this._terminateDrawing = function(){
            if (_this.currentGraphicElement) {
                if (_this.currentGraphicElement.width() === 0 || _this.currentGraphicElement.height() === 0) {
                    _this.currentGraphicElement.remove();
                } else {
                    if(_this.drawConfig['onDrawingEnd']){
                        _this.drawConfig['onDrawingEnd'](_this.currentGraphicElement);
                    }
                }                
            }
            _this.mousedownPos = null; 
            _this.currentGraphicElement = null;            
        };
        
        //??
        this.enableDrawingState();                        
    };

    /**
     * 启动‘矩形’绘制模式.
     * drawConfig : {
     *     resizable : true,
     *     editable : true,
     *     rectCls : 'textEditor'
     * } 
     */
    _DrawPallet.prototype.enableDrawRect = function(drawConfig){            
        var _this = this;                
        _this._terminateDrawing();               
        _this.drawConfig = drawConfig;
        
        //若当前模式即为‘绘制矩形’模式，不需要重新注册事件。
        if(_this.pallet.drawState === DrawState.RECT){
            return;
        }
        
        //pallet点击事件.
        _this.pallet.bind('click', function(e) {
            if( _this.palletConfig['onPalletClick'] ) {
                _this.palletConfig['onPalletClick'](e, _this);
            }
        });
                
        //注册mousemove事件.
        if(this.mousemoveHandler){
            this.pallet.unbind('mousemove', this.mousemoveHandler);
        }
        
        //绘制矩形时mousemove逻辑.
        this.mousemoveHandler = $.proxy( 
            function(e) {                    
                if (this.mousedownPos) {          
                    var palletOffset = $(this.pallet).offset();             
                    var left = Math.min(this.mousedownPos.x, e.pageX + this.palletContainer.scrollLeft() - palletOffset.left), 
                        top = Math.min(this.mousedownPos.y, e.pageY - palletOffset.top), 
                        width = Math.abs(this.mousedownPos.x - e.pageX - this.palletContainer.scrollLeft() + palletOffset.left), 
                        height = Math.abs(this.mousedownPos.y - e.pageY + palletOffset.top);                            
                    
                    if ( !this.currentGraphicElement ) {                
                        this.currentGraphicElement = this.addRect(this.drawConfig);
                    }
                    this.currentGraphicElement.css('left', left).css('top', top).css('width', width).css('height', height);
                }
            }, 
            this
        );
        this.pallet.bind({
            'mousemove' : this.mousemoveHandler
        });   
    };

    _DrawPallet.prototype.addRect = function(rectCfg, callback){
        var _this = this;
        var $graphicElement = $('<div class="graphicElement"></div>');
                        
        if(rectCfg['extraCls']){
            $graphicElement.addClass(rectCfg['extraCls']);    
        }
        
        if( rectCfg['text'] ) {
            var text = rectCfg['text'].unsafeString();
            var contentDiv = $graphicElement.find('.content');
            if( contentDiv.length ){
                contentDiv.html(text);
            } else {
                $graphicElement.append('<div class="content">{0}</div>'.format(text));
            }
        }
        
        this.pallet.append($graphicElement);
        
        if(rectCfg['resizable']){  
            DrawPallet.enableResizable($graphicElement, {
                onResizingFinished : this.drawConfig['onResizingFinished']
            });
        }
        if(rectCfg['movable'] !== false){
            DrawPallet.enableMovable($graphicElement);            
        }        
        if(rectCfg['editable']){
            DrawPallet.enableEditable($graphicElement);                   
        }         
                  
        $graphicElement
            .css('left', rectCfg['left'] || 0).css('top', rectCfg['top'] || 0)
            .css('width', rectCfg['width'] || 0).css('height', rectCfg['height'] || 0);
        
        
        $graphicElement.find('.content').bind({
            'focus': function() {
                var $self = $(this);
                $self.data('originalText', $self.text());
            },
            'blur': function() {
                var $self = $(this);
                if ($self.data('originalText') != $self.text()) {
                    
                    _this.drawConfig['onChange'] && _this.drawConfig['onChange']();
                }
            }
        });
        
        callback && callback($graphicElement);
            
        return $graphicElement;
    };

    _DrawPallet.prototype.enableSelectState = function(){
        this.pallet.removeClass('drawPallet').removeClass('unselectable');    
        this._terminateDrawing();
        this.pallet.unbind();
        this.pallet.undelegate();
        this.pallet.drawState = DrawState.SELECT;
    };
    
    _DrawPallet.prototype.enableDrawingState = function(){        
        var _this = this;        
        this.pallet.addClass('drawPallet').addClass('unselectable');        
        this.pallet.bind({
            'click' : function(){
                $(this).find('.graphicElement').removeClass('selected');
            },
            'mousedown' : function(e) {                
                
                if(_this.drawConfig['onDrawingStart'] && !_this.drawConfig['onDrawingStart']()){
                    return;
                }
                
                if (!$(e.target).closest('.graphicElement').length) {
                    var palletOffset = $(_this.pallet).offset();                    
                    _this.mousedownPos = {
                        x : e.pageX + _this.palletContainer.scrollLeft() - palletOffset.left,
                        y : e.pageY - palletOffset.top - 10
                    };
                }                             
            },
            'mouseup' : function(e) {                   
                _this._terminateDrawing();
            },
            'mouseout' : function(e){
                //由于drawPallet中可能存在很多内容，所以会频繁触发mouseout事件.
                if(!$(e.relatedTarget).closest('.drawPallet').length){
                    _this._terminateDrawing();    
                }
            }
        });
        
        this.pallet.delegate('.graphicElement', {
            'click' : function(e) {                
                $(this).addClass('selected').siblings().removeClass('selected');
                e.stopPropagation();
            }  
        });
    };
        
    ujs.define('DrawPallet', 'ujs.subjects.draw', {
        /**
         * 将pallet注册为画板.
         * @param {Object} pallet   :   jQuery selector.
         * @param {Object} palletConfig
         */
        register : function(pallet, palletConfig){
            return new _DrawPallet(pallet, palletConfig);
        },
        /**
         * 将drawPallet对象注销为dom元素.
         * @param {Object} drawPallet   : DrawPallet实例.
         */
        unregister : function (drawPallet) {
            drawPallet.enableSelectState();
        },        
        enableEditable : function($graphicElement){
            $graphicElement.addClass('editable');
            $graphicElement.editInplace({
                type : 'contentEditable',
                isShowSaveButton : false,
                isComplexEditor : true,
                editorCls : 'commentEditor',
                onSave : function(newText, originalText){
                    var minHeight = $(this).attr('minHeight') || 20;
                    var $contentDiv = $(this).find('.content');
                    var contentHeight = $contentDiv.length ? $contentDiv[0].scrollHeight : 0;
                    $(this).css('height', Math.max(minHeight, contentHeight));
                }           
            });
        },        
        enableMovable : function($graphicElement){
            $graphicElement.addClass('movable');
            $graphicElement.movable({
                onMove : function(){
                    window.annotationPallet.isModified = true;
                }
            });
        },        
        enableResizable : function($graphicElement, resizableConfig){
            $graphicElement.addClass('resizable');              
            $graphicElement.resizable(resizableConfig);
        }
    });
})(jQuery); 